home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / fpkpas92.zip / SRCRTL.ZIP / RTL / STRINGS.PP < prev   
Text File  |  1997-07-01  |  15KB  |  575 lines

  1. {****************************************************************************
  2.  
  3.                         FPKPascal Runtime-Library
  4.                   Copyright (c) 1993,94 by Florian Klämpfl
  5.  
  6.  ****************************************************************************}
  7. {
  8.   History:
  9.   1.5.1994: Version 0.9 
  10.             Unit ist komplett implementiert (noch nicht getestet)
  11.   20.3.1995: Version 0.91
  12.             strmove korriert, für system.move müssen Pointer
  13.             dereferenziert werden
  14.   24.12.1995: Version 0.92
  15.             strcomp war fehlerhaft; korrigiert
  16.             dito strlcomp
  17. }
  18.  
  19. unit strings;
  20.  
  21.   { Behandlung nullterminierter Strings }
  22.   { für alle Betriebssysteme            }
  23.  
  24.   interface
  25.  
  26.     {$E-}
  27.  
  28.     { stellt die Länge des Strings fest }
  29.     function strlen(p : pchar) : longint;
  30.  
  31.     { konvertiert einen Pascalstring in einen nullterminierten String }
  32.     function strpcopy(d : pchar;const s : string) : pchar;
  33.  
  34.     { wandelt einen nullterminierten String in einen Pascalstring um }
  35.     function strpas(p : pchar) : string;
  36.     
  37.     { kopiert source nach dest und liefert dest zurück }
  38.     function strcopy(dest,source : pchar) : pchar;
  39.     
  40.     { kopiert source nach dest und liefert dest zurück, wobei max.  }
  41.     { maxlen Zeichen kopiert werden                    }
  42.     function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
  43.     
  44.     { kopiert source nach dest und liefert einen Zeiger auf das    }
  45.     { abschließende #0-Zeichen                       }
  46.     function strecopy(dest,source : pchar) : pchar;
  47.     
  48.     { liefert einen Zeiger auf das abschließende #0-Zeichen von p  }
  49.     function strend(p : pchar) : pchar;
  50.     
  51.     { hängt source an dest an und gibt dest zurück                 }
  52.     function strcat(dest,source : pchar) : pchar;
  53.     
  54.     { vergleicht str1 und str2, liefert einen Wert <0 wenn         }
  55.     { str1<str2; 0 wenn str1=str2 und einen Wert >0 wenn str1>str2 }
  56.     function strcomp(str1,str2 : pchar) : longint;
  57.     
  58.     { wie strcomp, es werden jedoch maximal l Zeichen verglichen   }
  59.     function strlcomp(str1,str2 : pchar;l : longint) : longint;
  60.     
  61.     { wie strcomp jedoch ohne Beachtung der Groß- und Klein-       }
  62.     { schreibung                               }
  63.     function stricomp(str1,str2 : pchar) : longint;
  64.     
  65.     { kopiert l Zeichen von source nach dest              }
  66.     { und gibt dest zurück                      }
  67.     function strmove(dest,source : pchar;l : longint) : pchar;
  68.     
  69.     { hängt source an dest an, wobei dest maximal l Zeichen       }
  70.     { lang wird                              }
  71.     function strlcat(dest,source : pchar;l : longint) : pchar;
  72.     
  73.     { gibt einen Zeiger auf das erste Auftreten von c zurück,      }
  74.     { ansonsten nil                          }
  75.     function strscan(p : pchar;c : char) : pchar;
  76.     
  77.     { gibt einen Zeiger auf das letzte Auftreten von c zurück,      }
  78.     { ansonsten nil                          }
  79.     function strrscan(p : pchar;c : char) : pchar;
  80.     
  81.     { wandelt p in Kleinbuchstaben um und gibt p zurück          }
  82.     function strlower(p : pchar) : pchar;
  83.     
  84.     { wandelt p in Großbuchstaben um und gibt p zurück          }
  85.     function strupper(p : pchar) : pchar;
  86.     
  87.     { wie stricomp, jedoch maximal l Zeichen              }
  88.     function strlicomp(str1,str2 : pchar;l : longint) : longint;
  89.     
  90.     { liefert einen Zeiger auf das erste Auftreten von str2 in    }
  91.     { str2 ansonsten wird nil zurück gegeben                  }
  92.     function strpos(str1,str2 : pchar) : pchar;
  93.     
  94.     { legt eine Kopie von p auf dem Heap an und gibt einen Zeiger  }
  95.     { darauf zurück                           }
  96.     function strnew(p : pchar) : pchar;
  97.  
  98.     { löscht einen Zeiger vom Heap                   }
  99.     procedure strdispose(p : pchar);
  100.  
  101.   implementation
  102.   
  103.     function strcopy(dest,source : pchar) : pchar;
  104.     
  105.       begin
  106.          asm
  107.             cld
  108.             movl 12(%ebp),%edi
  109.             movl $0xffffffff,%ecx
  110.             xorb %al,%al
  111.             repne
  112.             scasb
  113.             not %ecx
  114.             movl 8(%ebp),%edi
  115.             movl 12(%ebp),%esi
  116.             movl %ecx,%eax
  117.             shrl $2,%ecx
  118.             rep
  119.             movsl
  120.             movl %eax,%ecx
  121.             andl $3,%ecx
  122.             rep
  123.             movsb
  124.             movl 8(%ebp),%eax
  125.             leave
  126.             ret $8
  127.          end;
  128.       end; 
  129.       
  130.     function strecopy(dest,source : pchar) : pchar;
  131.     
  132.       begin
  133.          asm
  134.             cld
  135.             movl 12(%ebp),%edi
  136.             movl $0xffffffff,%ecx
  137.             xorb %al,%al
  138.             repne
  139.             scasb
  140.             not %ecx
  141.             movl 8(%ebp),%edi
  142.             movl 12(%ebp),%esi
  143.             movl %ecx,%eax
  144.             shrl $2,%ecx
  145.             rep
  146.             movsl
  147.             movl %eax,%ecx
  148.             andl $3,%ecx
  149.             rep
  150.             movsb
  151.             movl 8(%ebp),%eax
  152.             decl %edi
  153.             movl %edi,%eax
  154.             leave
  155.             ret $8
  156.          end ['EAX','ESI','EDI'];
  157.       end;
  158.       
  159.     function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
  160.     
  161.       begin
  162.          asm
  163.             movl 8(%ebp),%edi
  164.             movl 12(%ebp),%esi
  165.             movl 16(%ebp),%ecx
  166.             cld
  167.          LSTRLCOPY1:
  168.             lodsb
  169.             stosb
  170.             decl %ecx        // max. Anzahl erniedrigen
  171.             jz LSTRLCOPY2    // 0 erreicht, dann Ende
  172.             orb %al,%al
  173.             jnz LSTRLCOPY1
  174.             movl 8(%ebp),%eax
  175.             leave
  176.             ret $12
  177.         LSTRLCOPY2:        
  178.             xorb %al,%al    // falls abgeschnitten wurde, noch
  179.             stosb        // ein #0 speichern
  180.             movl 8(%ebp),%eax
  181.             leave
  182.             ret $12
  183.          end ['EAX','ECX','ESI','EDI'];
  184.       end;
  185.  
  186.     function strlen(p : pchar) : longint;
  187.  
  188.       begin
  189.          asm
  190.             cld
  191.             movl 8(%ebp),%edi
  192.             movl $0xffffffff,%ecx
  193.             xorb %al,%al
  194.             repne
  195.             scasb
  196.             movl $0xfffffffe,%eax
  197.             subl %ecx,%eax
  198.             leave
  199.             ret $4
  200.          end ['EDI','ECX','EAX'];
  201.       end;
  202.  
  203.     function strend(p : pchar) : pchar;
  204.  
  205.       begin
  206.          asm
  207.             cld
  208.             movl 8(%ebp),%edi
  209.             movl $0xffffffff,%ecx
  210.             xorb %al,%al
  211.             repne
  212.             scasb
  213.             movl %edi,%eax
  214.             decl %eax
  215.             leave
  216.             ret $4
  217.          end ['EDI','ECX','EAX'];
  218.       end;
  219.  
  220.     function strpcopy(d : pchar;const s : string) : pchar;
  221.  
  222.       begin
  223.      asm
  224.         pushl %esi        // ESI wird nicht automatisch gerettet
  225.         cld
  226.         movl 8(%ebp),%edi    // Zieladresse laden
  227.         movl 12(%ebp),%esi   // Quelladresse laden
  228.         movl %edi,%ebx      // Rückgabewert speichern
  229.         lodsb        // Längenbyte laden und nach ECX
  230.         movzbl %al,%ecx
  231.         rep
  232.         movsb
  233.         xorb %al,%al    // Nullbyte speichern
  234.         stosb
  235.         movl %ebx,%eax    // Rückgabeadresse nach EAX
  236.         popl %esi
  237.         leave        // ... und fertig
  238.         ret $8
  239.      end ['EDI','ESI','EBX','EAX','ECX'];
  240.       end;
  241.  
  242.     function strpas(p : pchar) : string;
  243.  
  244.       begin
  245.          asm
  246.             cld
  247.             movl 12(%ebp),%edi
  248.             movl %edi,%esi               // Quelle
  249.             movl $0xffffffff,%ecx        // nach Ende suchen
  250.             xorb %al,%al
  251.             repne
  252.             scasb
  253.             notl %ecx
  254.             decl %ecx
  255.             movl 8(%ebp),%edi          //  Ziel neu laden
  256.             movb %cl,%al
  257.             stosb
  258.             rep                         
  259.             movsb                       
  260.          end ['ECX','EAX','ESI','EDI'];
  261.       end;
  262.       
  263.     function strcat(dest,source : pchar) : pchar;
  264.     
  265.       begin
  266.          strcat:=strcopy(strend(dest),source);
  267.       end;
  268.       
  269.     function strlcat(dest,source : pchar;l : longint) : pchar;
  270.     
  271.       var
  272.          destend : pchar;
  273.     
  274.       begin
  275.          destend:=strend(dest);
  276.          l:=l-(destend-dest);
  277.          strlcat:=strlcopy(destend,source,l);
  278.       end;
  279.       
  280.     function strcomp(str1,str2 : pchar) : longint;
  281.     
  282.       begin
  283.          asm
  284.             // Nullbyte im ersten String suchen
  285.             movl 12(%ebp),%edi
  286.             movl $0xffffffff,%ecx
  287.             cld
  288.             xorl %eax,%eax
  289.             repne
  290.             scasb
  291.             not %ecx
  292.             movl 12(%ebp),%edi
  293.             movl 8(%ebp),%esi
  294.             repe
  295.             cmpsb
  296.             movb -1(%esi),%al
  297.             movzbl -1(%edi),%ecx
  298.             subl %ecx,%eax
  299.             leave
  300.             ret $8
  301.          end ['EAX','ECX','ESI','EDI'];
  302.       end;
  303.       
  304.     function strlcomp(str1,str2 : pchar;l : longint) : longint;
  305.     
  306.       begin
  307.          asm
  308.             // Nullbyte im ersten String suchen
  309.             movl 12(%ebp),%edi
  310.             movl $0xffffffff,%ecx
  311.             cld
  312.             xorl %eax,%eax
  313.             repne
  314.             scasb
  315.             not %ecx
  316.             cmpl 16(%ebp),%ecx
  317.             jl LSTRLCOMP1
  318.             movl 16(%ebp),%ecx
  319.         LSTRLCOMP1:
  320.             movl 12(%ebp),%edi
  321.             movl 8(%ebp),%esi
  322.             repe
  323.             cmpsb
  324.             movb -1(%esi),%al
  325.             movzbl -1(%edi),%ecx
  326.             subl %ecx,%eax
  327.             leave
  328.             ret $12
  329.          end ['EAX','ECX','ESI','EDI'];
  330.       end;
  331.       
  332.     function stricomp(str1,str2 : pchar) : longint;
  333.     
  334.       begin
  335.          asm
  336.             // Nullbyte im ersten String suchen
  337.             movl 12(%ebp),%edi
  338.             movl $0xffffffff,%ecx
  339.             cld
  340.             xorl %eax,%eax
  341.             repne
  342.             scasb
  343.             not %ecx
  344.             movl 12(%ebp),%edi
  345.             movl 8(%ebp),%esi
  346.        LSTRICOMP2:
  347.             repe
  348.             cmpsb
  349.             jz LSTRICOMP3    // falls Ende erreicht dann herausspringen            
  350.             movb (%esi),%al
  351.             movzbl (%edi),%ebx
  352.             cmpb $97,%al
  353.             jb LSTRICOMP1
  354.             cmpb $122,%al
  355.             ja LSTRICOMP1
  356.             subb $0x20,%al
  357.         LSTRICOMP1:
  358.             cmpb $97,%bl
  359.             jb LSTRICOMP4
  360.             cmpb $122,%bl
  361.             ja LSTRICOMP4
  362.             subb $0x20,%bl
  363.        LSTRICOMP4:
  364.             subl %ebx,%eax
  365.             jz LSTRICOMP2    // falls immer noch gleich nochmals
  366.                                  // vergleichen
  367.        LSTRICOMP3:
  368.             leave
  369.             ret $8
  370.          end ['EAX','ECX','ESI','EDI'];
  371.       end;
  372.       
  373.     function strlicomp(str1,str2 : pchar;l : longint) : longint;
  374.     
  375.       begin
  376.          asm
  377.             // Nullbyte im ersten String suchen
  378.             movl 12(%ebp),%edi
  379.             movl $0xffffffff,%ecx
  380.             cld
  381.             xorl %eax,%eax
  382.             repne
  383.             scasb
  384.             not %ecx
  385.             cmpl 16(%ebp),%ecx
  386.             jl LSTRLICOMP5
  387.             movl 16(%ebp),%ecx
  388.        LSTRLICOMP5:
  389.             movl 12(%ebp),%edi
  390.             movl 8(%ebp),%esi
  391.        LSTRLICOMP2:
  392.             repe
  393.             cmpsb
  394.             jz LSTRLICOMP3    // falls Ende erreicht dann herausspringen            
  395.             movb (%esi),%al
  396.             movzbl (%edi),%ebx
  397.             cmpb $97,%al
  398.             jb LSTRLICOMP1
  399.             cmpb $122,%al
  400.             ja LSTRLICOMP1
  401.             subb $0x20,%al
  402.         LSTRLICOMP1:
  403.             cmpb $97,%bl
  404.             jb LSTRLICOMP4
  405.             cmpb $122,%bl
  406.             ja LSTRLICOMP4
  407.             subb $0x20,%bl
  408.        LSTRLICOMP4:
  409.             subl %ebx,%eax
  410.             jz LSTRLICOMP2    // falls immer noch gleich nochmals
  411.                                  // vergleichen
  412.        LSTRLICOMP3:
  413.             leave
  414.             ret $12
  415.          end ['EAX','ECX','ESI','EDI'];
  416.       end;
  417.       
  418.     function strmove(dest,source : pchar;l : longint) : pchar;
  419.     
  420.       begin
  421.          move(source^,dest^,l);
  422.          strmove:=dest;
  423.       end;
  424.       
  425.     function strscan(p : pchar;c : char) : pchar;
  426.     
  427.       begin
  428.          asm
  429.             movl 8(%ebp),%edi
  430.             movl $0xffffffff,%ecx
  431.             cld
  432.             xorb %al,%al
  433.             repne
  434.             scasb
  435.             not %ecx
  436.             movb 12(%ebp),%al
  437.             movl 8(%ebp),%edi
  438.             repne
  439.             scasb
  440.             movl $0,%eax    // EAX löschen, wenn bis Ende verglichen
  441.                         // dann nil zurückgeben
  442.             jnz LSTRSCAN
  443.             movl %edi,%eax    // sonst den um 1 erniedrigten Wert von
  444.                         // EDI nach EAX
  445.             decl %eax
  446.         LSTRSCAN:
  447.             leave
  448.             ret $6
  449.          end;
  450.       end;
  451.       
  452.     function strrscan(p : pchar;c : char) : pchar;
  453.       
  454.       begin
  455.          asm
  456.             movl 8(%ebp),%edi
  457.             movl $0xffffffff,%ecx
  458.             cld
  459.             xorb %al,%al
  460.             repne
  461.             scasb
  462.             not %ecx
  463.             movb 12(%ebp),%al
  464.             movl 8(%ebp),%edi
  465.             addl %ecx,%edi
  466.             decl %edi
  467.             std
  468.             repne
  469.             scasb
  470.             movl $0,%eax    // EAX löschen, wenn bis Ende verglichen
  471.                         // dann nil zurückgeben
  472.             jnz LSTRSCAN
  473.             movl %edi,%eax    // sonst den um 1 erhöhten Wert von
  474.                         // EDI nach EAX
  475.             incl %eax
  476.         LSTRRSCAN:
  477.             leave
  478.             ret $6
  479.          end;
  480.       end;
  481.       
  482.     function strupper(p : pchar) : pchar;
  483.     
  484.       begin
  485.          asm
  486.             movl 8(%ebp),%esi
  487.             movl %esi,%edi
  488.          LSTRUPPER1:
  489.             lodsb
  490.             cmpb $97,%al
  491.             jb LSTRUPPER3
  492.             cmpb $122,%al
  493.             ja LSTRUPPER3
  494.             subb $0x20,%al
  495.          LSTRUPPER3:
  496.             stosb
  497.             orb %al,%al
  498.             jnz LSTRUPPER1
  499.             movl 8(%ebp),%eax
  500.             leave
  501.             ret $4
  502.          end;
  503.       end;
  504.       
  505.     function strlower(p : pchar) : pchar;
  506.     
  507.       begin
  508.          asm
  509.             movl 8(%ebp),%esi
  510.             movl %esi,%edi
  511.          LSTRLOWER1:
  512.             lodsb
  513.             cmpb $65,%al
  514.             jb LSTRLOWER3
  515.             cmpb $90,%al
  516.             ja LSTRLOWER3
  517.             addb $0x20,%al
  518.          LSTRLOWER3:
  519.             stosb
  520.             orb %al,%al
  521.             jnz LSTRLOWER1
  522.             movl 8(%ebp),%eax
  523.             leave
  524.             ret $4
  525.          end;
  526.       end;
  527.       
  528.     function strpos(str1,str2 : pchar) : pchar;
  529.     
  530.       var
  531.          p : pchar;
  532.          lstr2 : longint;
  533.     
  534.       begin
  535.          strpos:=nil;
  536.          p:=strscan(str1,str2^);
  537.          if p=nil then
  538.            exit;
  539.          lstr2:=strlen(str2);
  540.          while p<>nil do
  541.            begin
  542.               if strlcomp(p,str2,lstr2)=0 then
  543.                 begin
  544.                    strpos:=p;
  545.                    exit;
  546.                 end;
  547.               inc(longint(p));
  548.               p:=strscan(p,str2^);
  549.            end;
  550.       end;
  551.  
  552.     procedure strdispose(p : pchar);
  553.     
  554.       begin
  555.          if p<>nil then
  556.            freemem(p,strlen(p)+1);
  557.       end;
  558.       
  559.     function strnew(p : pchar) : pchar;
  560.     
  561.       var
  562.          len : longint;
  563.     
  564.       begin
  565.          strnew:=nil;
  566.          if (p=nil) or (p^=#0) then
  567.            exit;
  568.          len:=strlen(p)+1;
  569.          getmem(strnew,len);
  570.          if strnew<>nil then
  571.            strmove(strnew,p,len);
  572.       end;
  573.  
  574. end.
  575.